logo头像

野渡's小小知识乐园

《TCP-IP详解卷1》第3章 IP:网际协议

IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输。但是IP提供不可靠、无连接的数据报传送服务

不可靠在于它不能保证IP数据报能成功到达目的地,仅提供最好的传输服务。IP在传输服务时出现错误(如,路由器的缓冲区用完了),直接丢弃该数据报,然后通过ICMP消息给信源端。任何可靠性都必须由上层如TCP来提供。

无连接意味着IP不维护任何关于后续数据报的状态信息,每个数据报的处理都是独立的,可以不按顺序接收。不同的数据报都要独立地进行路由选择,可能选择不同的路线。

在本章,我们将简要介绍IP首部中的各个字段,讨论IP路由选择和子网的有关内容。还要介绍两个有用的命令:ifconfig和netstat。

1、IP首部

IP数据报的格式如下图所示。普通的IP首部长为20个字节,除非含有选项字段。

image

IP的数据存储中,最高位在左边,记为0 bit;最低位在右边,记为31 bit。传输时则先0-7bit,最后24-31bit。也就是从高位到低位进行传输,这种传输顺序叫做Big endian字节序,由于TCP/IP首部的二进制整数也是这种传输顺序,因此也叫做网络字节序。以其他形式存储二进制整数的机器,如little endian格式,则必须在传输数据之前把首部转换成网络字节序。

  • (1) 目前版本协议号是4,因此IP有时也称作IPv4。
  • (2) 首部长度指的是首部占32bit字的数目,因此首部最长为60个字节(15*4)。普通IP数据报(没有任何选择项)字段的值是5。
  • (3) 服务类型(TOS):包括一个3 bit的优先权子字段(现在已被忽略),4 bit的TOS子字段和1 bit未用位但必须置0。4 bit的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。现在大多数的TCP/IP实现都不支持TOS特性,
  • (4) 总字段长度是指整个IP数据报的长度,以字节为单位。所以IP数据报最长可达65535字节。尽管最长可传输65535字节的IP数据报,但是大多数的链路层都会对它进行分片。主机限制用户数据报长度为512字节,小于576字节。利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。如果没有总长度字段,那么IP层就不知道46字节中有多少是IP数据报的内容。
  • (5) 标识字段唯一的标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1。
    (6)TTL(Time to live):生存时间字段设置了数据报可以经过的最多路由器数。通常为32或64。一旦经过一个处理它的路由器,它的值就减去1。当该字段的值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。
  • (7) 首部检验和字段是根据IP首部计算的校验和码。方法:对首部中每个16bit进行二进制反码求和。结果存在检验和字段中。
  • (8) 每一份IP数据报都包含源IP地址和目的IP地址。
  • (9) 最后一个字段是任选项,是数据报中的一个可变长的可选信息。选项字段一直都是以32bit作为界限,在必要的时候插入值为0的填充字节。

2、IP路由选择

IP路由过程中,如果目的主机与源主机直接相连或都在一个共享网络上(以太网或令牌环网),那么IP数据报就直接送到目的主机上。否则,主机把数据报发往一默认的路由器上,由路由器来转发该数据报。

IP层在内存中有一个路由表。当收到一份数据报并进行发送时,都要对该表搜索一次。当数据报来自某个网络接口时,IP首先检查目的IP地址是否为本机的IP地址之一或者IP广播地址。如果是,数据报就被送到由IP首部协议字段所指定的 协议模块进行处理,如果不是,则对数据包进行路由或者丢弃。

路由表中包含以下几项信息:

  • (1) 目的IP地址;
  • (2) 下一站(下一跳)路由器(next-hop-router)的IP地址,或者有直接连接的网络IP地址。
  • (3) 标识。其中一个标识指明目的IP地址是网络地址还是主机地址,另一个标识指明下一站路由器是否为真正的下一站路由器,还是一个直接相连的接口。
  • (4) 为数据报的传输指定一个网络接口。

IP路由选择主要完成以下功能

  • (1) 搜索路由表,寻找能与目的IP地址完全匹配的表目;如果找到,则把报文发送给该表目指定的下一站路由器或直接连接的网络接口。
  • (2) 搜索路由表,寻找能与目的网络号相匹配的表目;如果找到,则把报文发送给该表目指定的下一站路由器或直接连接的网络接口。
  • (3) 搜索路由表,寻找默认路由表的表目。如果找到,则把报文发送给该表目指定的下一站路由器。

为一个网络指定一个路由器,而不必为每个主机指定一个路由器,这是IP路由选择机制的另一个基本特性。这样做可以极大地缩小路由表的规模,比如Internet上的路由器有只有几千个表目,而不会是超过100万个表目。

IP数据包在路由时,需要注意以下几点:
(1) 数据报中的目的IP地址始终不发生任何变化。
(2) 每个链路层可能具有不同的数据帧首部,数据帧中的目的MAC地址始终指的是下一站结点的MAC地址。

3、子网寻址

现在所有的主机都要求支持子网编址。不是把IP地址看成由单纯的一个网络号和一个主机号组成,而是把主机号再分成一个子网号和一个主机号。样做的原因是因为A类和B类地址为主机号分配了太多的空间,事实上,在一个网络中人们并不安排这么多的主机。例如,这里有一个B类网络地址(140.252..),在剩下的16bit中,8bit用于子网号,8bit用于主机号。这样就允许25 4个子网,每个子网可以有254台主机(0或全1的主机号都是无效的,因此我们把总数减去2)。

子网对外部路由器来说隐藏了内部网络组织的细节,对于外部来说只需要一个IP地址即可,这样能极大地缩减路由表的规模,对于内部来说各个子网又互相透明,体会不到划分的存在。

4、子网掩码

主机在引导时进行的部分配置之一是指定主机的IP地址。除了IP地址以外,主机还需要知道有多少比特用于子网号及多少比特用于主机号,而这是在引导过程中通过子网掩码来确定的。这个掩码是一个32 bit的值,其中值为1的比特留给网络号和子网号,为0的比特留给主机号。

子网掩码却经常用十六进制来表示,特别是当界限不是一个字节时,因为子网掩码是一个比特掩码。给定IP地址和子网掩码以后,主机就可以确定IP数据报的目的地址(本子网、其他子网、其他网络)。

image

如果知道本机的IP地址,也就知道网络号和子网号之间的分界线。而根据子网掩码就可知道子网号与主机号之间的分界线。比较时由网络号到子网号到主机号。

5、特殊情况的IP地址

下图介绍7个特殊的IP地址,在这个图中,0表示所有的比特位全为0;-1表示所有的比特位全为1;netid、subnetid和hostid分别表示不为全0或全1的对应字段。

image

表的头两项是特殊的源地址,中间项是特殊的环回地址,最后四项是广播地址。表中的头两项,网络号为0,如主机使用BOOTP协议确定本机IP地址时只能作为初始化过程中的源地址出现。

6、ifconfig命令

到目前为止,我们已经讨论了链路层和IP层,现在可以介绍TCP/IP对网络接口进行配置和查询的命令了。ifconfig命令一般在引导时运行,以配置主机上的每个接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@DESKTOP-QI6PGJM:/mnt/d/wsl_workspace/MyCode_GitHub# ifconfig -a
eth0 Link encap:Ethernet HWaddr 40:8d:5c:0e:35:c9
inet addr:172.16.10.38 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::50d0:c0b7:e553:b163/64 Scope:Unknown
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Unknown
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

环回接口被认为是一个网络接口。它是一个A类地址,没有进行子网划分。

ifconfig命令一般支持TCP/IP以外的其他协议族,而且有很多参数。关于这些细节可以查看系统说明书。

7、netstat命令

netstat命令也提供系统上的接口信息。-i参数将打印出接口信息,-n参数则打印出IP地址,而不是主机名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
root@DESKTOP-QI6PGJM:/mnt/d/wsl_workspace/MyCode_GitHub# netstat -i
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 0 0 0 0 0 0 0 0 BMRU
eth1 1500 0 0 0 0 0 0 0 0 0 BMRU
eth2 1500 0 0 0 0 0 0 0 0 0 BMRU
lo 1500 0 0 0 0 0 0 0 0 0 LRU

root@DESKTOP-QI6PGJM:/mnt/d/wsl_workspace/MyCode_GitHub# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path

8、小结

本章开始描述了IP首部的格式,并简要讨论了首部中的各个字段。我们还介绍了IP路由选择,并指出主机的路由选择可以非常简单:如果目的主机在直接相连的网络上,那么就把数据报直接传给目的主机,否则传给默认路由器。

在进行路由选择决策时,主机和路由器都使用路由表。在表中有三种类型的路由:特定主机型、特定网络型和默认路由型。路由表中的表目具有一定的优先级。在选择路由时,主机路由优先于网络路由,最后在没有其他可选路由存在时才选择默认路由。

IP路由选择是通过逐跳来实现的。数据报在各站的传输过程中目的IP地址始终不变,但是封装和目的链路层地址在每一站都可以改变。大多数的主机和许多路由器对于非本地网络的数据报都使用默认的下一站路由器。

A类和B类地址一般都要进行子网划分。用于子网号的比特数通过子网掩码来指定子网的划分缩小了Internet路由表的规模,因为许多网络经常可以通过单个表目就可以访问了。接口和网络的有关信息通过ifconfig和netstat命令可以获得,包括接口的IP地址、子网掩码、广播地址以及MTU等。

在本章的最后,我们对Internet协议族潜在的改进建议—下一代IP进行了讨论。